package cz.semjobKB.search.impl;

import cz.semjobKB.conllx.node.EConstituent;
import cz.semjobKB.search.api.INodeRule;
import cz.semjobKB.search.api.IRule;
import cz.semjobKB.search.api.RuleCorrectnessException;

import java.util.ArrayList;
import java.util.List;

public class Rule implements IRule {

	String name;

	List<INodeRule> nodes;
	
	boolean isVassal = false;

    /**
     * Constructor
     * @param ruleName  Rule name
     * @param vassal    False only for a predicate if the rule can be extended by other rules
     *                  that contain this rule as a part
     */
	public Rule(String ruleName, boolean vassal) {
		this.name = ruleName;
		this.isVassal = vassal;
		this.nodes = new ArrayList<INodeRule>();
	}

	public String getName() {
		return name;
	}

	public void addNode(INodeRule node) throws RuleCorrectnessException {
		if (node != null) {			
			nodes.add((NodeRule) node);
		}
		RuleCorrect();
	}

	public List<INodeRule> getNodes() {
		return nodes;
	}

	public boolean isVassal() {
		return this.isVassal;
	}

    /*
     *   Validates correctness of the rule
     */
	private void RuleCorrect() throws RuleCorrectnessException {
		int parentNodeCount = 0;		
		List<EConstituent> listTypes = new ArrayList<EConstituent>();

		for (INodeRule node : nodes) {
			if (node.getParentType() == null) {
				parentNodeCount++;
			}
			listTypes.add(node.getType());
		}
		if (parentNodeCount != 1) {
			throw new RuleCorrectnessException("No parent node presented");
		}

		for (int position = 1; position < nodes.size(); position++) {
			boolean found = false;
			for (int iterator = 0; iterator < position; iterator++) {
				if (nodes.get(iterator).getType() == nodes.get(position).getParentType()) {
					found = true;
				}
				if (nodes.get(iterator).getType() == nodes.get(position).getType() 
						&& nodes.get(iterator).getParentType() == nodes.get(position).getParentType()) {
					throw new RuleCorrectnessException("Node duplicated. Type:" +  nodes.get(position).getType());
				}
				if (!found) {
					throw new RuleCorrectnessException("Parant node not found. Type:" +  nodes.get(position).getType() + " Parent type: " + nodes.get(position).getParentType());
				}
			}
		}			
	}

}
